#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

char *codestr = NULL;

int processKeyBack(char *s, char *key)
{
	char *ts, *_ts, *__ts;
	size_t keylen = 0;
	if (s == NULL || key == NULL)
		return -1;
	ts = s;
	keylen = strlen(key);
	while(1) {
        	ts = strstr(ts, key);
		if (ts == NULL) 
			return 0;
        	if (*(ts + keylen) == '(') {
                	memmove(ts+keylen+1, ts+keylen, (size_t)strlen(ts+keylen));
                	*(ts+keylen)=' ';
			ts = ts + keylen;
       		} else {
			ts = ts + keylen; 
			continue;
		}
	}
	return 0;
}

int processPMBack(char *s)
{
        char *ts;
        if (s == NULL)
                return -1;
	
	// ;
        ts = s;
        while(1) {
                ts = strstr(ts, ";");
		if (ts == NULL)
			break;
                if (*(ts + 1) != ' ' && *(ts + 1) != '\n') {
                        memmove(ts+2, ts+1, strlen(ts+1));
                        *(ts+1)=' ';
                        ts = ts + 1;
                } else {
			ts = ts + 1;	
                        continue;
                }
        }
	
	// , 
	ts = s;
        while(1) {
                ts = strstr(ts, ",");
                if (ts == NULL)
                        break;
                if (*(ts + 1) != ' ' && *(ts + 1) != '\n') {
                        memmove(ts+2, ts+1, strlen(ts+1));
                        *(ts+1)=' ';
                        ts = ts + 1;
                } else {
                        ts = ts + 1;
                        continue;
                }
        }

        return 0;
}

int processOpt(char *s)
{
	if (s == NULL)	return -1;
	
	char *ts;
	// == 
	ts = s;
	while (1) {
		ts = strstr(ts, "==");
		if (ts != NULL) {
			if (*(ts+2) != ' ') {
				memmove(ts+3, ts+2, strlen(ts+2));
				*(ts+2) = ' ';
			}
			if (*(ts-1) != ' ' && *(ts-1) != '>' && *(ts-1) != '<') {
				memmove(ts+1, ts, strlen(ts));
				*ts = ' ';
			}
			ts = ts + 3;
		} else {
			break;
		}
		
	}	
	
	// &&
	ts = s;
        while (1) {
                ts = strstr(ts, "&&");
                if (ts != NULL) {
                        if (*(ts+2) != ' ') {
                                memmove(ts+3, ts+2, strlen(ts+2));
                                *(ts+2) = ' ';
                        }
                        if (*(ts-1) != ' ' && *(ts-1) != '>' && *(ts-1) != '<') {
                                memmove(ts+1, ts, strlen(ts));
                                *ts = ' ';
                        }
                        ts = ts + 3;
                } else {
                        break;
                }

        }
	
	// ||
	ts = s;
        while (1) {
                ts = strstr(ts, "||");
                if (ts != NULL) {
                        if (*(ts+2) != ' ') {
                                memmove(ts+3, ts+2, strlen(ts+2));
                                *(ts+2) = ' ';
                        }
                        if (*(ts-1) != ' ' && *(ts-1) != '>' && *(ts-1) != '<') {
                                memmove(ts+1, ts, strlen(ts));
                                *ts = ' ';
                        }
                        ts = ts + 3;
                } else {
                        break;
                }

        }
	


	// =
	ts = s;
        while (1) {
                ts = strstr(ts, "=");
                if (ts != NULL) {
			if (*(ts+1) == '=') {
				ts = ts + 2;
				continue;
			}
                        if (*(ts+1) != ' ') {
                                memmove(ts+2, ts+1, strlen(ts+1));
                                *(ts+1) = ' ';
                        }
                        if (*(ts-1) != ' ' && *(ts-1) != '<' && *(ts-1) != '>') {
                                memmove(ts+1, ts, strlen(ts));
                                *ts = ' ';
                        }
                        ts = ts + 2;
                } else {
                        break;
                }

        }
	
	// < 
	ts = s;
        while (1) {
                ts = strstr(ts, "<");
                if (ts != NULL) {
                        if (*(ts+1) != '=') {
                                memmove(ts+2, ts+1, strlen(ts+1));
                                *(ts+1) = ' ';
                        }
                        if (*(ts-1) != ' ') {
                                memmove(ts+1, ts, strlen(ts));
                                *ts = ' ';
                        }
                        ts = ts + 2;
                } else {
                        break;
                }

        }

	// >
        ts = s;
        while (1) {
                ts = strstr(ts, ">");
                if (ts != NULL) {
			if (*(ts-1) == '-') {
				ts = ts + 2;
				continue;
			}
                        if (*(ts+1) != '=') {
                                memmove(ts+2, ts+1, strlen(ts+1));
                                *(ts+1) = ' ';
                        }
                        if (*(ts-1) != ' ') {
                                memmove(ts+1, ts, strlen(ts));
                                *ts = ' ';
                        }
                        ts = ts + 2;
                } else {
                        break;
                }

        }	

	return 0;
}

int processSpecial(char *s)
{
	char *ts, *_ts;
	if (s == NULL)
		return -1;

	// when "){" occar
	ts = s;
        while (1) {
                ts = strstr(ts, "){");
                if (ts != NULL) {
			memmove(ts+2, ts+1, (size_t)strlen(ts+1));
			*(ts+1) = ' ';
                        ts = ts + 2;
		} else {
                        break;
                }

        }
	
	// when ")\r\n\t?{" occar
	ts = s;
        while (1) {
                ts = strstr(ts, ")\r\n");
                if (ts != NULL) {
			_ts = strchr(ts, '\t');
			while (*(_ts+1) != '{') {
				_ts = _ts + 1;
				_ts = strchr(_ts, '{');
				if(_ts == NULL)
					break;
			}
			if (_ts == NULL) {
				ts = ts + 2;
				continue;
			}
                        memmove(ts+2, _ts+1, (size_t)strlen(_ts+1));
                        *(ts+1) = ' ';
                        ts = ts + 2;
                } else {
                        break;
                }

        }
	
	// when ")\n\t?{" occar
	ts = s;
	while (1) {
                ts = strstr(ts, ")\n");
                if (ts != NULL) {
                        _ts = strchr(ts, '\t');
                        while (*(_ts+1) != '{') {
                                _ts = _ts + 1;
                                _ts = strchr(_ts, '{');
                                if(_ts == NULL)
                                        break;
                        }
                        if (_ts == NULL) {
                                ts = ts + 2;
                                continue;
                        }
                        memmove(ts+2, _ts+1, (size_t)strlen(_ts+1));
                        *(ts+1) = ' ';
                        ts = ts + 2;
                } else {
                        break;
                }

        }

 
	return 0;
}

int processFileEnd(char *s)
{
	char *filetail;
	if (s == NULL)
		return -1;
	filetail = s + strlen(s) - 1;
	while (1) {
		if (*filetail == '\r' || *filetail == '\n' || *filetail == '\t') {
			*filetail = '\0';
			filetail--;
		} else {
			break;
		}
	}
}

int processManFail(char *s)
{
        char *ts;
        if (s == NULL)
                return -1;
	ts = s;
        while (1) {
		ts = strchr(ts, '\b');
                if (ts != NULL) {
			if (*(ts-1) != '_') {
				memmove(ts, ts+2, (size_t)strlen(ts+2));
			} else {
				memmove(ts-1, ts+1, (size_t)strlen(ts+1));
			}
                } else {
			break;
                }
        }
}

int processMutiSpace(char *s)
{
        char *ts;
        if (s == NULL)
                return -1;
        ts = s;
        while (1) {
                ts = strstr(ts, "   ");
                if (ts != NULL) {
			memmove(ts, ts+2, (size_t)strlen(ts+2));
        	} else {
			return 0;
		}
	}
	return 0;
}

int main(int argc, char **argv)
{
	int fd = -1;
	struct stat fileinfo;
	if (argc <= 1) {
		printf("Usge: ./exec filename\n");
		return -1;
	}
	codestr = malloc(1024*1024*3);
	if (codestr==NULL)
		return -1;
	fd = open(argv[1], O_RDWR, 0755);
	if (fd == -1) {
		printf("open file failed!\n");
		return -1;
	}

	fstat(fd, &fileinfo);
	//printf("file size:%d\n", fileinfo.st_size);
	
	read(fd, codestr, fileinfo.st_size);
	//printf("file content is:\n%s\n", codestr);

	//
	{
		processManFail(codestr);
		processMutiSpace(codestr);
		processFileEnd(codestr);
	}
	
	close(fd);
	
	fd = open("tmp.c", O_CREAT|O_RDWR, 0755);
	if (fd == -1) {
		printf("open file failed!\n");
		return -1;
	}

	write(fd, codestr, strlen(codestr));

	close(fd);
	
	printf("finish!\n");	

	return 0;
}
